package com.web3.management.service;

import com.web3.management.entity.TmClient;
import com.web3.management.exception.BusinessException;
import com.web3.management.repository.TmClientRepository;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * Tampermonkey 客户端管理服务
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class TmClientService {

    private final TmClientRepository tmClientRepository;

    @Transactional
    public TmClient ensureRegistered(String clientId) {
        if (!StringUtils.hasText(clientId)) {
            throw new BusinessException("clientId 不能为空");
        }
        Optional<TmClient> optional = tmClientRepository.findByClientId(clientId);
        if (optional.isPresent()) {
            return optional.get();
        }
        TmClient client = new TmClient();
        client.setClientId(clientId.trim());
        client.setStatus("ACTIVE");
        client.setLastSeenAt(new Date());
        return tmClientRepository.save(client);
    }

    @Transactional
    public TmClient bindClient(Integer accountId, String clientId, String remark) {
        TmClient client = ensureRegistered(clientId);
        tmClientRepository.findByAccountId(accountId)
                .filter(existing -> !existing.getClientId().equals(client.getClientId()))
                .ifPresent(existing -> {
                    existing.setAccountId(null);
                    existing.setRemark("自动解绑：绑定至新的客户端");
                    tmClientRepository.save(existing);
                });
        client.setAccountId(accountId);
        client.setRemark(remark);
        client.setStatus("ACTIVE");
        client.setLastSeenAt(new Date());
        return tmClientRepository.save(client);
    }

    @Transactional
    public void unbindClient(Integer accountId, String clientId) {
        TmClient client = tmClientRepository.findByClientId(clientId)
                .orElseThrow(() -> new BusinessException("客户端不存在"));
        if (client.getAccountId() == null || !client.getAccountId().equals(accountId)) {
            throw new BusinessException("客户端未绑定到指定账号");
        }
        client.setAccountId(null);
        client.setRemark("管理员解绑");
        tmClientRepository.save(client);
    }

    @Transactional
    public void updateHeartbeat(String clientId) {
        tmClientRepository.findByClientId(clientId).ifPresent(client -> {
            client.setLastSeenAt(new Date());
            tmClientRepository.save(client);
        });
    }

    public Optional<TmClient> findByClientId(String clientId) {
        return tmClientRepository.findByClientId(clientId);
    }

    public Optional<TmClient> findByAccountId(Integer accountId) {
        return tmClientRepository.findByAccountId(accountId);
    }

    public Map<Integer, TmClient> findByAccountIds(List<Integer> accountIds) {
        if (accountIds == null || accountIds.isEmpty()) {
            return Collections.emptyMap();
        }
        return tmClientRepository.findByAccountIdIn(accountIds).stream()
                .collect(Collectors.toMap(TmClient::getAccountId, client -> client, (a, b) -> a));
    }

    @Transactional
    public TmClient save(TmClient client) {
        return tmClientRepository.save(client);
    }
}
